package com.example.firstboot.util;


/*Web请求日志*/
/*
AOP面向切面编程
* 1.添加依赖
* 2.*/

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component
@Aspect
/*特殊的动态代理*/
public class WebLog {

    /*创建日志管理工厂*/
    private final Logger LOGGER = LoggerFactory.getLogger(WebLog.class);

    /*设置切面工厂*/
    @Pointcut("execution(* com.example.firstboot.controller.*.*(..))")
    /*第一个*是指方法的返回值类型
     * .*.*controller包下所有类 所有方法
     * （..） 所有的参数*/
    public void webLog() {

    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        LOGGER.info("=================================开始记录日志============================");
        /*1.记录IP*/
        LOGGER.info("IP:{}",request.getRemoteAddr());
        /*2.记录URL*/
        LOGGER.info("URL:{}", request.getRequestURL());
        /*URI是方法名
        * URL是请求路径*/

        /*3.记录获取请求的方法*/
        LOGGER.info("HTTP Methods:{}", request.getMethod());
        /*4.记录请求路径*/
        LOGGER.info("Class Method:{}", joinPoint.getSignature().getDeclaringType(), joinPoint.getSignature().getName());
        /*5.请求参数*/
        Object[] args = joinPoint.getArgs();
        /*
        以stream流的形式过滤对象
        处理数据的流
        先判断是否为空，如果不为空转换为*/
        Stream<?> stream = ArrayUtils.isEmpty(args) ? Stream.empty() : Arrays.asList(args).stream();

        List<Object> logArgs = stream.filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse)))
                .collect(Collectors.toList());

        /*转化为JSON*/
        String str = JSON.toJSONString(logArgs);
        LOGGER.info("Request args :{}",str);


    }

    @After("webLog()")
    public void doAfter() {
        LOGGER.info("=================================结束记录日志============================");
    }

    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        /*记录执行时间 和返回类内容*/
        Long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        /*将返回值转化成JSON字符串*/
        LOGGER.info("Response args :{}", new JSONObject().toJSONString(result));

        Long endTime = System.currentTimeMillis();

        LOGGER.info("Time Consuming :{}",endTime-startTime+"ms");
        return result;
    }

}
